package com.css.dzj.dzjap.modules.lawenforcesuper.service.impl;

import com.css.dzj.dzjap.common.util.Constant;
import com.css.dzj.dzjap.common.util.R;
import com.css.dzj.dzjap.common.util.RandomUtil;
import com.css.dzj.dzjap.common.util.ServiceUtil;
import com.css.dzj.dzjap.modules.info.entity.ApExpertEntity;
import com.css.dzj.dzjap.modules.info.service.ExpertService;
import com.css.dzj.dzjap.modules.lawenforcesuper.entity.*;
import com.css.dzj.dzjap.modules.lawenforcesuper.mapper.DrawExpertRelationMapper;
import com.css.dzj.dzjap.modules.lawenforcesuper.mapper.SupersiveExpertInfoMapper;
import com.css.dzj.dzjap.modules.lawenforcesuper.service.SuperTaskService;
import com.css.dzj.dzjap.modules.lawenforcesuper.service.SupersiveExpertService;
import com.css.dzj.dzjap.sys.user.entity.LoginUser;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;


/**
 * 专家抽出service实现类
 * @author limanman
 */
@Service
public class SupersiveExpertServiceImpl implements SupersiveExpertService {
    @Autowired
    private SupersiveExpertInfoMapper supersiveExpertInfoMapper;
    @Autowired
    private DrawExpertRelationMapper drawExpertRelationMapper;
    @Autowired
    private ExpertService expertService;
    @Autowired
    private JPAQueryFactory jpaQueryFactory;
    @Autowired
    private SuperTaskService superTaskService;
    @Autowired
    private ServiceUtil serviceUtil;


    /**
     * 查询抽取专家信息表
     * @param taskId
     * @param recordId
     * @return
     */
    @Override
    public List<ApSupersiveExpertInfoEntity> querySupersiveExpertOnly(String taskId, String recordId) {
        try {
            if (!"".equals(taskId) && taskId!=null && !"".equals(recordId) && recordId!=null){
                QApSupersiveExpertInfoEntity qApSupersiveExpertInfoEntity = QApSupersiveExpertInfoEntity.apSupersiveExpertInfoEntity;
                List<ApSupersiveExpertInfoEntity> apSupersiveExpertInfoEntities = jpaQueryFactory.selectFrom(qApSupersiveExpertInfoEntity)
                        .where(qApSupersiveExpertInfoEntity.taskId.eq(taskId), qApSupersiveExpertInfoEntity.recordId.eq(recordId))
                        .fetch();
                return apSupersiveExpertInfoEntities;
            }
            return null;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 查询抽取的专家关联表
     * @param pageable
     * @param recordId
     * @param taskId
     * @return
     */
    @Override
    public QueryResults<DrawExpertRelationErpertEntity> queryExpertRelationInfo(Pageable pageable, String recordId,String taskId) {
        try {
            QDrawExpertRelationErpertEntity qDrawExpertRelationErpertEntity = QDrawExpertRelationErpertEntity.drawExpertRelationErpertEntity;
            Predicate predicate = qDrawExpertRelationErpertEntity.isNotNull().or(qDrawExpertRelationErpertEntity.isNull());
            predicate = ("".equals(recordId) || recordId ==null ) ? predicate : ExpressionUtils.and(predicate,qDrawExpertRelationErpertEntity.recordId.eq(recordId));
            predicate = ("".equals(taskId) || taskId ==null )? predicate :ExpressionUtils.and(predicate,qDrawExpertRelationErpertEntity.taskId.eq(taskId));
            return jpaQueryFactory.selectFrom(qDrawExpertRelationErpertEntity)
                    .where(predicate)
                    .offset(pageable.getOffset())
                    .limit(pageable.getPageSize())
                    .fetchResults();
        }catch (Exception e){
            e.printStackTrace();
            return  null;
        }
    }

    /**
     * 查询抽取的专家
     * @param pageable
     * @param recordId
     *  @param taskId
     * @return
     */
    @Override
    public QueryResults<ApExpertEntity> queryExpertById(Pageable pageable, String recordId,String taskId) {
        try {
            if (!"".equals(taskId) && taskId!=null && !"".equals(recordId) && recordId!=null){
                List<ApExpertEntity> apExpertEntities = new ArrayList<ApExpertEntity>();
                QueryResults<DrawExpertRelationErpertEntity>  page= queryExpertRelationInfo(pageable,recordId,taskId);
                List<DrawExpertRelationErpertEntity> drawExpertRelationErpertEntities=page.getResults();
                if (!StringUtils.isEmpty(drawExpertRelationErpertEntities) && drawExpertRelationErpertEntities.size()>0){
                    for(DrawExpertRelationErpertEntity drawExpertRelationErpertEntity:drawExpertRelationErpertEntities){
                        apExpertEntities.add(expertService.findById(drawExpertRelationErpertEntity.getExpertId()));
                    }
                    QueryResults<ApExpertEntity> queryResults = new QueryResults(apExpertEntities,page.getLimit(),page.getOffset(),page.getTotal());
                    return queryResults;
                }
            }
            return null;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 保存抽取专家的两张表（新增的方法）
     * @param list
     * @return
     */
    @Override
    @Transactional(noRollbackFor = RuntimeException.class)
    public R saveSupersiveExpert(List<ApSupersiveExpertInfoEntity> list, HttpServletRequest request) {

        try {
            if ("".equals(list) || list.size()<=0) {
                throw new RuntimeException("新增不能为空");
            }
            /**
             * 获取suser
             */
            R r = serviceUtil.getUserInfoByRequest(request);
            String suserName = "";
            String location = "";
            String address="";
            String userUnit ="";
            if(r.getCode().equals("200")){
                LoginUser userInfo =  (LoginUser)r.get("data");
                /**
                 * 获取用户名
                 */
                suserName =userInfo.getLoginName();
                /**
                 * 获取用户的省份
                 */
                String orgName = userInfo.getOrgName();
                location = orgName.replace("地震局","");
                address = userInfo.getAddress();
                userUnit= userInfo.getOrgName();
            }
            List<ApSupersiveExpertInfoEntity> listApSupersiveExpertInfo = new ArrayList<ApSupersiveExpertInfoEntity>();
            DrawExpertRelationErpertEntity drawExpertRelationErpertEntity;
            List<DrawExpertRelationErpertEntity> drawExpertRelationErpertEntities = new ArrayList<>();
            String expertSuperId;
            String unitLocation ;
            /**
             * 抽取专家总数
             */
            Integer expertNum = 0;
            for(ApSupersiveExpertInfoEntity apSupersiveExpertInfoEntity:list){
                if("".equals(apSupersiveExpertInfoEntity.getMajor()) || apSupersiveExpertInfoEntity.getMajor()==null){
                    throw new RuntimeException("抽取专家专业不能为空！");
                }
                apSupersiveExpertInfoEntity.setId(UUID.randomUUID().toString());
                apSupersiveExpertInfoEntity.setCreateTime(new Date());
                apSupersiveExpertInfoEntity.setCreatePerson(suserName);
                apSupersiveExpertInfoEntity.setExtractPersonDept(userUnit);
                expertSuperId = apSupersiveExpertInfoEntity.getId();
                /**
                 * 抽取的项目所属单位的地址
                 */
                unitLocation =  apSupersiveExpertInfoEntity.getRecordExpertAddress();
                expertNum =apSupersiveExpertInfoEntity.getExpertNum();
                if (expertNum <= 0) {
                    throw new RuntimeException("抽取专家数量不能为0");
                }

                if (location.contains(Constant.LOCATIONZG)){
                    if (apSupersiveExpertInfoEntity.getCountryRatio()+apSupersiveExpertInfoEntity.getProvinceRatio()!=100){
                        throw new RuntimeException("抽取比例错误，抽取比例总和应为100%！");
                    }
                }else {
                    if (apSupersiveExpertInfoEntity.getCountryRatio()+apSupersiveExpertInfoEntity.getProvinceRatio()+apSupersiveExpertInfoEntity.getCityRatio()!=100){
                        throw new RuntimeException("抽取比例错误，抽取比例总和应为100%！");
                    }
                }

                /**
                 *抽取国家专家的人数
                 */
                int i = 0;
                double countryNum = apSupersiveExpertInfoEntity.getCountryRatio() * expertNum / 100.0;
                Integer country = Integer.parseInt(new BigDecimal(countryNum).setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                double cd = countryNum-countryNum;
                if (cd == 0.5){
                    i++;
                }
                Integer bdcountryNum = Integer.parseInt(new BigDecimal(countryNum).setScale(0, BigDecimal.ROUND_HALF_UP).toString());
                /**
                 *抽取省内专家的人数
                 */
                double provienceNum = apSupersiveExpertInfoEntity.getProvinceRatio() * expertNum / 100.0;
                Integer provience = Integer.parseInt(new BigDecimal(provienceNum).setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                double dp = provienceNum-provience;
                Integer bdprovienceNum = 0;
                if (dp==0.5){
                    if (i>0){
                        bdprovienceNum = Integer.parseInt(new BigDecimal(provienceNum).setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                    }
                }else {
                    bdprovienceNum = Integer.parseInt(new BigDecimal(provienceNum).setScale(0, BigDecimal.ROUND_HALF_UP).toString());
                }
                /**
                 *抽取省外专家的人数
                 */
                Integer bdcityNum = expertNum-bdprovienceNum-bdcountryNum;

                /**
                 * 数据库数量
                 */
                if (bdcountryNum < 0) {
                    throw new RuntimeException("抽取国家级比例不能小于0！");
                } else {
                    List<ApExpertEntity> countryAapExpertEntities = expertService.listExpert(Constant.STATE_LEVEL,apSupersiveExpertInfoEntity.getMajor(),apSupersiveExpertInfoEntity.getUnitName(),location,Constant.COUNTRYNO);//国家
                    if (bdcountryNum <= countryAapExpertEntities.size()) {
                        /**
                         * 随机选择
                         */
                        List<ApExpertEntity> countryRandomList = RandomUtil.ramdonExtract(countryAapExpertEntities, bdcountryNum.toString());
                        if (!StringUtils.isEmpty(countryRandomList) && countryRandomList.size() > 0) {
                            for (ApExpertEntity apExpertEntity : countryRandomList) {
                                drawExpertRelationErpertEntity = new DrawExpertRelationErpertEntity();
                                drawExpertRelationErpertEntity.setCreateTime(new Date());
                                drawExpertRelationErpertEntity.setCreatePerson(suserName);
                                drawExpertRelationErpertEntity.setExpertId(apExpertEntity.getExpertId());
                                drawExpertRelationErpertEntity.setExpertSuperId(expertSuperId);
                                drawExpertRelationErpertEntity.setRecordId(apSupersiveExpertInfoEntity.getRecordId());
                                drawExpertRelationErpertEntity.setTaskId(apSupersiveExpertInfoEntity.getTaskId());
                                drawExpertRelationErpertEntities.add(drawExpertRelationErpertEntity);
                            }
                        }
                    }else {
                        throw new RuntimeException("符合抽取条件的国家级专家数量不足！");
                    }
                }

                if (bdprovienceNum < 0) {
                    throw new RuntimeException("抽取省内比例不能小于0！");
                } else {
                    List<ApExpertEntity> provienceApExpertEntities = expertService.listExpert(Constant.PROVIENCE_LEVEL,apSupersiveExpertInfoEntity.getMajor(),apSupersiveExpertInfoEntity.getUnitName(),location,Constant.PROVIENCEIN);//省内
                    if (bdprovienceNum <= provienceApExpertEntities.size()) {
                        /**
                         * 随机选择
                         */
                        List<ApExpertEntity> provienceRandomList = RandomUtil.ramdonExtract(provienceApExpertEntities, bdprovienceNum.toString());
                        if (!StringUtils.isEmpty(provienceRandomList) && provienceRandomList.size() > 0 ) {
                            for (ApExpertEntity apExpertEntity : provienceRandomList) {
                                drawExpertRelationErpertEntity = new DrawExpertRelationErpertEntity();
                                drawExpertRelationErpertEntity.setCreateTime(new Date());
                                drawExpertRelationErpertEntity.setCreatePerson(suserName);
                                drawExpertRelationErpertEntity.setExpertId(apExpertEntity.getExpertId());
                                drawExpertRelationErpertEntity.setExpertSuperId(expertSuperId);
                                drawExpertRelationErpertEntity.setRecordId(apSupersiveExpertInfoEntity.getRecordId());
                                drawExpertRelationErpertEntity.setTaskId(apSupersiveExpertInfoEntity.getTaskId());
                                drawExpertRelationErpertEntities.add(drawExpertRelationErpertEntity);
                            }
                        }
                    }else {
                        throw new RuntimeException("符合抽取条件的专家数量不足！");
                    }
                }

                if (bdcityNum < 0) {
                    throw new RuntimeException("抽取省外比例不能小于0！");
                } else {
                    List<ApExpertEntity> cityApExpertEntities = expertService.listExpert(Constant.PROVIENCE_LEVEL,apSupersiveExpertInfoEntity.getMajor(),apSupersiveExpertInfoEntity.getUnitName(),location,Constant.PROVIENCEOUT);//省外
                    if (bdcityNum <= cityApExpertEntities.size()) {
                        /**
                         * 随机选择
                         */
                        List<ApExpertEntity> cityRandomList = RandomUtil.ramdonExtract(cityApExpertEntities, bdcityNum.toString());
                        if (!StringUtils.isEmpty(cityRandomList) && cityRandomList.size() > 0 ) {
                            for (ApExpertEntity apExpertEntity : cityRandomList) {
                                drawExpertRelationErpertEntity = new DrawExpertRelationErpertEntity();
                                drawExpertRelationErpertEntity.setCreateTime(new Date());
                                drawExpertRelationErpertEntity.setCreatePerson(suserName);
                                drawExpertRelationErpertEntity.setExpertId(apExpertEntity.getExpertId());
                                drawExpertRelationErpertEntity.setExpertSuperId(expertSuperId);
                                drawExpertRelationErpertEntity.setRecordId(apSupersiveExpertInfoEntity.getRecordId());
                                drawExpertRelationErpertEntity.setTaskId(apSupersiveExpertInfoEntity.getTaskId());
                                drawExpertRelationErpertEntities.add(drawExpertRelationErpertEntity);
                            }
                        }
                    }else {
                        throw new RuntimeException("符合抽取条件的专家数量不足！");
                    }
                }
                listApSupersiveExpertInfo.add(apSupersiveExpertInfoEntity);

                superTaskService.updSuperTask(apSupersiveExpertInfoEntity.getTaskId(), apSupersiveExpertInfoEntity.getRecordId());
            }

            if (!StringUtils.isEmpty(drawExpertRelationErpertEntities) && drawExpertRelationErpertEntities.size() > 0) {
                drawExpertRelationMapper.saveAll(drawExpertRelationErpertEntities);
            }
            if (!StringUtils.isEmpty(listApSupersiveExpertInfo) && listApSupersiveExpertInfo.size() > 0) {
                supersiveExpertInfoMapper.saveAll(listApSupersiveExpertInfo);
            }
            return R.ok();
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
    }


}
